package com.brainhealth.customer.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.brainhealth.common.constant.Constants;
import com.brainhealth.common.constant.NextChatFlagConstants;
import com.brainhealth.common.constant.NumberConstants;
import com.brainhealth.common.constant.PunctuationConstants;
import com.brainhealth.common.enums.*;
import com.brainhealth.customer.config.MinioConfig;
import com.brainhealth.customer.domain.*;
import com.brainhealth.customer.domain.vo.ChatAiVO;
import com.brainhealth.customer.domain.vo.ChatVO;
import com.brainhealth.customer.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wll
 * 处理获取聊天内容返回结果
 */
@Service
public class ChatContentService {

    /**
     * 日志
     */
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    MinioConfig minioConfig;

    @Autowired
    IChatRecordService chatRecordService;

    /**
     * 会员训练记录
     */
    @Autowired
    private ICustomerExerciseService customerExerciseService;

    /**
     * 订单
     */
    @Autowired
    private IExerciseOrderService exerciseOrderService;

    /**
     * 每日报告
     */
    @Autowired
    ICustomerReportTimeService customerReportTimeService;

    /**
     * 7天报告，28天报告
     */
    @Autowired
    ICustomerReportCycleService customerReportCycleService;

    @Autowired
    private IExerciseService exerciseService;
    /**
     * 文心一言会话
     */
    @Autowired
    IAIChatService aiChatService;

    /**
     * 获取聊天内容结果
     *
     * @param chatTemplateList
     * @param chatQueryParam
     * @param customer
     * @return
     */
    public ChatVO getChatVo(List<ChatTemplate> chatTemplateList, ChatQueryParam chatQueryParam, Customer customer,List<CustomerExercise> notFinishedCustomerExerciseList,List<CustomerExercise> finishedCustomerExerciseList,List<CustomerExercise> expiredCustomerExerciseList) {
        if (chatTemplateList.size() == 1) {
            ChatTemplate chatTemplate = chatTemplateList.get(0);
            ChatVO chatVO = constructChatVO(chatTemplate, chatQueryParam, customer);
            return chatVO;
        } else if (chatTemplateList.size() > 1) {
            ChatTemplate chatTemplate = getChatTemplate(customer, chatTemplateList,notFinishedCustomerExerciseList,finishedCustomerExerciseList,expiredCustomerExerciseList);
            ChatVO chatVO = constructChatVO(chatTemplate, chatQueryParam, customer);
            return chatVO;
        } else {
            logger.warn("未找到模板数据");
            return new ChatVO();
        }
    }

    private ChatTemplate getChatTemplate(Customer customer, List<ChatTemplate> chatTemplateList,List<CustomerExercise> notFinishedCustomerExerciseList,List<CustomerExercise> finishedCustomerExerciseList,List<CustomerExercise> expiredCustomerExerciseList) {
        ChatTemplate template = chatTemplateList.get(0);
        if (null != template.getChatCategory1Id() &&
                ChatCategoryEnum.SIGN.getCategory1Code() == template.getChatCategory1Id()) {
            //签到成功
            int size = chatTemplateList.size();
            Random random = new Random();
            int randNumber = random.nextInt(size);
            ChatTemplate chatTemplate = chatTemplateList.stream().filter(item -> item.getId() % size == randNumber).collect(Collectors.toList()).get(0);
            return chatTemplate;
        }else if(  null != template.getChatCategory1Id()
                && ChatCategoryEnum.OVER_TIPS.getCategory1Code().equals(template.getChatCategory1Id())
        ){
            Integer category1Code = ChatCategoryEnum.OVER_TIPS.getCategory1Code();
            Integer tmpCategory2Code = NumberConstants.ONE;
            if (CollectionUtils.isEmpty(notFinishedCustomerExerciseList)
                    && exerciseService.getCompletedState(finishedCustomerExerciseList,expiredCustomerExerciseList)) {
                tmpCategory2Code = NumberConstants.TWO;
            }
            final Integer category2Code = tmpCategory2Code;
            chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id() == category1Code).filter(item -> item.getChatCategory2Id() == category2Code).collect(Collectors.toList());
            ChatTemplate chatTemplate = chatTemplateList.get(0);

            return chatTemplate;

        } else if (
                null != template.getChatCategory1Id()
                        && null != template.getChatCategory2Id()
                        && null != template.getChatCategory3Id()
                        && ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory1Code().equals(template.getChatCategory1Id())
                        && ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory2Code().equals(template.getChatCategory2Id())
        ) {
            //知识分享
            Long nextContentId = getNextContentId(customer, chatTemplateList);

            Integer category1Code = ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory1Code();
            Integer category2Code = ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory2Code();
            final Integer category3Code = nextContentId.intValue();
            chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id() == category1Code).filter(item -> item.getChatCategory2Id() == category2Code).filter(item -> item.getChatCategory3Id() == category3Code).collect(Collectors.toList());
            ChatTemplate chatTemplate = chatTemplateList.get(0);

            return chatTemplate;
        }else if(
                null != template.getChatCategory1Id()
                        && ChatCategoryEnum.MORE_FUNC.getCategory1Code().equals(template.getChatCategory1Id())
        ){
            ChatAiTokens chatAiTokens = new ChatAiTokens();
            chatAiTokens.setCustomerId(customer.getCustomerId());
            String orderNo = exerciseOrderService.getOrderNo(customer);
            chatAiTokens.setOrderNo(orderNo);
            chatAiTokens.setCourseNo(customer.getCountSort());
            ChatAiVO chatAiVO = aiChatService.getChatAiVO(chatAiTokens);
            if (
                    (null != chatAiVO &&
                            null != chatAiVO.getCount() &&
                            null != chatAiVO.getTotalTokens())&&
                            chatAiVO.getTotalTokens() > NumberConstants.TWO_THOUSAND) {
                Integer category1Code = ChatCategoryEnum.MORE_FUNC_1.getCategory1Code();
                Integer category2Code = ChatCategoryEnum.MORE_FUNC_1.getCategory2Code();
                chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id() == category1Code).filter(item -> item.getChatCategory2Id() == category2Code).collect(Collectors.toList());
                ChatTemplate chatTemplate = chatTemplateList.get(0);

                return chatTemplate;
            }
            Integer category1Code = ChatCategoryEnum.MORE_FUNC_2.getCategory1Code();
            Integer category2Code = ChatCategoryEnum.MORE_FUNC_2.getCategory2Code();
            chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id() == category1Code).filter(item -> item.getChatCategory2Id() == category2Code).collect(Collectors.toList());
            ChatTemplate chatTemplate = chatTemplateList.get(0);

            return chatTemplate;
        } else{
            return chatTemplateList.get(0);
        }
    }

    //String getOrderNo(Customer customer)
    //{
    //    ExerciseOrder exerciseOrderParam = new ExerciseOrder();
    //    exerciseOrderParam.setStatus(PayStatus.Exercise);
    //    ExerciseOrder exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);

    //    exerciseOrderParam.setStatus(PayStatus.Finish);
    //    ExerciseOrder finishExerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);

    //    return null!=exerciseOrder? exerciseOrder.getOrderId():finishExerciseOrder.getOrderId();
    //}

    private Long getNextContentId(Customer customer, List<ChatTemplate> chatTemplateList) {
        //获取订单id
        //订单编号
        ExerciseOrder exerciseOrderParam = new ExerciseOrder();
        exerciseOrderParam.setStatus(PayStatus.Exercise);
        ExerciseOrder exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        if (null==exerciseOrder){
            exerciseOrderParam.setStatus(PayStatus.Finish);
            exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        }
        ChatRecord chatRecordQuery = new ChatRecord();
        chatRecordQuery.setCustomerId(customer.getCustomerId());
        chatRecordQuery.setOrderNo(exerciseOrder.getOrderId());
        chatRecordQuery.setInputType(InputTypeEnum.KNOWLEDGE.getCode());
        List<ChatRecord> chatRecordList = chatRecordService.selectChatRecordList(chatRecordQuery);
        if (CollectionUtils.isEmpty(chatRecordList)) {
            return 1L;
        }
        chatRecordList = chatRecordList.stream().sorted(Comparator.comparing(ChatRecord::getCreateTime).reversed()).collect(Collectors.toList());
        ChatRecord chatRecord = chatRecordList.get(0);
        String content = chatRecord.getContent();
        ChatContent chatContent = JSONObject.parseObject(content, ChatContent.class);
        Long contentId = chatContent.getContentId();
        Long maxId = getMaxKnowledgeContentId(chatTemplateList);
        Long nextContentId = 0L;
        if (null == contentId ||
                contentId == maxId) {
            nextContentId = 1L;
        } else {
            nextContentId = contentId + 1;
        }
        return nextContentId;
    }

    private Long getMaxKnowledgeContentId(List<ChatTemplate> chatTemplateList) {
        Integer category1Code = ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory1Code();
        Integer category2Code = ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory2Code();
        chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id() == category1Code).filter(item -> item.getChatCategory2Id() == category2Code).collect(Collectors.toList());
        OptionalLong max = chatTemplateList.stream().mapToLong(ChatTemplate::getChatCategory3Id).max();
        List<ChatTemplate> collect = chatTemplateList.stream().filter(item -> item.getChatCategory3Id() == max.getAsLong()).collect(Collectors.toList());
        ChatTemplate chatTemplate = collect.get(0);
        return Long.valueOf(chatTemplate.getChatCategory3Id());
    }

    private ChatVO constructChatVO(ChatTemplate chatTemplate, ChatQueryParam chatQueryParam, Customer customer) {
        if (null == chatTemplate)
            return null;
        ChatVO chatVO = new ChatVO();
        BeanUtils.copyProperties(chatTemplate, chatVO);
        chatVO.setChatId(chatQueryParam.getChatId());
        Map<String, Long> map = customerExerciseService.getProgressMap(customer);
        chatVO.setNextId(chatTemplate.getNextChatFlag());
        if (chatTemplate.getIsPlaceholderContent() == YNEnum.YES.getCode()) {
            String nickName = StringUtils.isBlank(customer.getNickName()) ? chatQueryParam.getName() : customer.getNickName();
            chatVO.setContent(chatVO.getContent().replace(Constants.MARK_NAME, nickName));
            if (MapUtils.isNotEmpty(map)) {
                chatVO.setContent(chatVO.getContent().replace(Constants.MARK_COMPLETED_DAYS, String.valueOf(map.get(Constants.MARK_COMPLETED_DAYS))));
                chatVO.setContent(chatVO.getContent().replace(Constants.MARK_REMIND_DAYS, String.valueOf(map.get(Constants.MARK_REMIND_DAYS))));
            }
        }
        if (chatTemplate.getInputType() == InputTypeEnum.EXERCISE_CARD_GAME.getCode()
                || chatTemplate.getInputType() == InputTypeEnum.EXERCISE_CARD_VIDEO.getCode()
        ) {
            CustomerExercise customerExercise = getCustomerExercise(chatTemplate,customer);
            if (null != customerExercise) {
                chatVO.setExerciseId(customerExercise.getExerciseId());
                chatVO.setCustomerExerciseId(customerExercise.getCustomerExerciseId());
                chatVO.setStatus(customerExercise.getStatus().getCode());
            }
        }
        //订单编号
        ExerciseOrder exerciseOrderParam = new ExerciseOrder();
        exerciseOrderParam.setStatus(PayStatus.Exercise);
        ExerciseOrder exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        if (null==exerciseOrder){
            exerciseOrderParam.setStatus(PayStatus.Finish);
            exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        }
        chatVO.setOrderNo(exerciseOrder.getOrderId());
        CustomerChatStatus chatStatus = customer.getChatStatus();
        Integer hallFlag = chatStatus == CustomerChatStatus.Register ? YNEnum.NO.getCode() : YNEnum.YES.getCode();
        chatVO.setIsShowLearningHall(hallFlag);

        if (chatTemplate.getInputType() == InputTypeEnum.REPORT_CARD_DAY.getCode()
                || chatTemplate.getInputType() == InputTypeEnum.REPORT_CARD_SEVEN.getCode()
                || chatTemplate.getInputType() == InputTypeEnum.REPORT_CARD_TWENTY_EIGHT.getCode()) {
            int reportId = getReportId(exerciseOrder.getOrderId(), customer.getCustomerId(), customer.getCountSort(), chatTemplate.getInputType());
            chatVO.setReportId(reportId);
        }

        chatVO.setCourseNo(customer.getCountSort());

        if (chatQueryParam.getChatId().equals(NextChatFlagConstants.RETURN_KNOWLEDGE) &&
                chatQueryParam.getCourseStatus() == ExerciseStatusEnum.OVER.getCode()) {
            chatVO.setNextId(NextChatFlagConstants.RETURN_END);
        }
        //知识分享
        if (chatTemplate.getInputType() == InputTypeEnum.KNOWLEDGE.getCode()) {
            chatVO.setContentId(chatTemplate.getChatCategory3Id().longValue());
        }
        //返回青竹知识分享
        if (chatQueryParam.getChatId().equals(NextChatFlagConstants.RETURN_KNOWLEDGE)) {
            chatVO.setNextId(NextChatFlagConstants.RETURN_END);
        }

        //处理语音
        handWaveContent(chatVO, chatTemplate, map);

        //处理文心一言入口
        handChatEntrance(chatVO,chatTemplate);

        return chatVO;
    }


    private CustomerExercise getCustomerExercise(ChatTemplate chatTemplate,Customer customer)
    {
        int exerciseType=ExerciseType.Video.getCode();
        if (chatTemplate.getInputType() == InputTypeEnum.EXERCISE_CARD_GAME.getCode()){
            exerciseType=ExerciseType.Game.getCode();
        }
        Long countSort = customer.getCountSort();
        ExerciseOrder exerciseOrder = exerciseOrderService.getExerciseOrder(customer);

        CustomerExercise exercise=new CustomerExercise();
        exercise.setCustomerId(customer.getCustomerId());
        exercise.setOrderId(exerciseOrder.getOrderId());
        exercise.setCountSort(countSort);
        exercise.setExerciseType(Long.valueOf(exerciseType));
        List<CustomerExercise> customerExerciseList = customerExerciseService.selectCustomerExerciseList(exercise);
        if (CollectionUtils.isEmpty(customerExerciseList)) {
            logger.warn("未查询到该用户的训练记录，入参 {}", exercise);
            return null;
        }
        if (customerExerciseList.size()>NumberConstants.ONE) {
            logger.warn("查询到多条用户的训练记录，入参 {}", exercise);
        }
        return customerExerciseList.get(NumberConstants.ZERO);
    }

    private int getReportId(String orderNo, Long customerId, Long countSort, Integer inputType) {
        logger.info("orderNo：{},customerId：{},countSort：{},inputType：{}", orderNo, customerId, countSort, inputType);
        if (inputType == InputTypeEnum.REPORT_CARD_DAY.getCode()) {
            CustomerReportTime customerReportTime = new CustomerReportTime();

            customerReportTime.setCountSort(countSort);
            customerReportTime.setCustomerId(customerId);
            customerReportTime.setOrderId(orderNo);

            List<CustomerReportTime> customerReportTimeList = customerReportTimeService.selectCustomerReportTimeList(customerReportTime);
            if (CollectionUtils.isEmpty(customerReportTimeList)) {
                return NumberConstants.NEGATIVE_ONE;
            }
            if (customerReportTimeList.size() > NumberConstants.ONE) {
                logger.warn("会员：{},订单：{},课程：{}存在多个报告", customerId, orderNo, countSort);
            }
            return customerReportTimeList.get(0).getCustomerReportTimeId().intValue();
        }

        ReportType reportType=ReportType.First_7;
        if (countSort== NumberConstants.TWENTY_EIGHT){
            reportType=ReportType.Time_28;
        }
        CustomerReportCycle customerReportCycle = new CustomerReportCycle();
        customerReportCycle.setCustomerId(customerId);
        customerReportCycle.setOrderId(orderNo);
        customerReportCycle.setReportType(reportType);
        List<CustomerReportCycle> customerReportCycleList = customerReportCycleService.selectCustomerReportCycleList(customerReportCycle);
        if (CollectionUtils.isEmpty(customerReportCycleList)) {
            return NumberConstants.NEGATIVE_ONE;
        }
        if (customerReportCycleList.size() > NumberConstants.ONE) {
            logger.warn("会员：{},订单：{},课程：{}存在多个报告", customerId, orderNo, countSort);
        }
        return customerReportCycleList.get(0).getCustomerReportCycleId().intValue();
    }

    public void handWaveContent(ChatVO chatVO, ChatTemplate chatTemplate, Map<String, Long> map) {
        if (chatTemplate.getRole().equals(RoleEnum.QING_ZHU.getCode())) {
            //没有替换内容
            if (chatTemplate.getIsPlaceholderContent().equals(YNEnum.NO.getCode())
                    && InputTypeEnum.getVoiceCodeList().contains(chatTemplate.getInputType())
            ) {
                String waveUrl = chatTemplate.getWaveUrl();
                constructWaveContent(chatVO, waveUrl);
                return;
            }
            //有提换内容，提醒部分

            if (chatTemplate.getChatCategory1Id().equals(ChatCategoryEnum.REMIND_COMPLETED_COUNT_2.getCategory1Code())
                    && chatTemplate.getChatCategory2Id().equals(ChatCategoryEnum.REMIND_COMPLETED_COUNT_2.getCategory2Code())
                    && chatTemplate.getChatCategory3Id().equals(ChatCategoryEnum.REMIND_COMPLETED_COUNT_2.getCategory3Code())
            ) {
                Long completedDays = map.get(Constants.MARK_COMPLETED_DAYS);
                String waveUrl = getDynamicWaveUrl(chatTemplate, completedDays.intValue());
                constructWaveContent(chatVO, waveUrl);
                return;
            }
            if (chatTemplate.getChatCategory1Id().equals(ChatCategoryEnum.REMIND_COMPLETED_COUNT_3.getCategory1Code())
                    && chatTemplate.getChatCategory2Id().equals(ChatCategoryEnum.REMIND_COMPLETED_COUNT_3.getCategory2Code())
                    && chatTemplate.getChatCategory3Id().equals(ChatCategoryEnum.REMIND_COMPLETED_COUNT_3.getCategory3Code())
            ) {
                Long completedDays = map.get(Constants.MARK_COMPLETED_DAYS);
                String waveUrl = getDynamicWaveUrl(chatTemplate, completedDays.intValue());
                constructWaveContent(chatVO, waveUrl);
                return;
            }
            if (chatTemplate.getChatCategory1Id().equals(ChatCategoryEnum.REMIND_REMIND.getCategory1Code())
                    && chatTemplate.getChatCategory2Id().equals(ChatCategoryEnum.REMIND_REMIND.getCategory2Code())
            ) {
                Long remindDays = map.get(Constants.MARK_REMIND_DAYS);
                String waveUrl = getDynamicWaveUrl(chatTemplate, remindDays.intValue());
                constructWaveContent(chatVO, waveUrl);
                return;
            }

        }
        //无语音
        chatVO.setWaveFlag(YNEnum.NO.getCode());
        return;
    }

    private void constructWaveContent(ChatVO chatVO, String waveUrl) {
        chatVO.setWaveFlag(YNEnum.YES.getCode());
        String qingZhuVoiceParentPath = minioConfig.getQingZhuVoiceParentPath();
        waveUrl = qingZhuVoiceParentPath.concat(waveUrl);

        chatVO.setWaveUrl(waveUrl);
    }

    public static final String SUFFIX_WAV = "WAV";

    private String getDynamicWaveUrl(ChatTemplate chatTemplate, Integer count) {
        String category = String.format("%s%s%s", chatTemplate.getChatCategory1Id(), chatTemplate.getChatCategory2Id(), chatTemplate.getChatCategory3Id());
        Long chatId = chatTemplate.getChatId();
        String waveUrl = String.format("category%s", chatTemplate.getChatCategory1Id()).concat(PunctuationConstants.SLASH);
        waveUrl = waveUrl.concat(String.format("%s_%s_%s", category, chatId, count).concat(PunctuationConstants.DOT).concat(SUFFIX_WAV));

        return waveUrl;
    }

    private void handChatEntrance(ChatVO chatVO,ChatTemplate chatTemplate)
    {
        Integer chatCategory1Id = chatTemplate.getChatCategory1Id();
        if ( null==chatVO.getInputType()
                || null ==chatCategory1Id
                || !InputTypeEnum.ERNIE_BOT.getCode().equals(chatVO.getInputType())){
            return;
        }
        if (ChatCategoryEnum.ENTER_EXERCISE.getCategory1Code().equals(chatCategory1Id)){
            chatVO.setChatEntrance(ErnieBotEntranceEnum.ENTRANCE_1_BEFORE_EXERCISE.getCode());
        }
        if (ChatCategoryEnum.MORE_FUNC.getCategory1Code().equals(chatCategory1Id)){
            chatVO.setChatEntrance(ErnieBotEntranceEnum.ENTRANCE_2_AFTER_EXERCISE.getCode());
        }
        if (ChatCategoryEnum.ERNIE_BOT_ENTRANCE.getCategory1Code().equals(chatCategory1Id)){
            chatVO.setChatEntrance(ErnieBotEntranceEnum.ENTRANCE_3_ASK_MOOD.getCode());
        }
    }
}
